var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
define(["require", "exports", "N/log", "N/record", "N/runtime", "N/search", "N/format", "N/file", "./YLES_RELATED_RECORDTYPE", "./papaparse", "./YLES_SEARCH_TOOL"], function (require, exports, log, record, runtime, search, format, file, YLES_RELATED_RECORDTYPE_1, Papa, YLES_SEARCH_TOOL_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.changeImportLog = exports.PapaValidateData = exports.validateData = exports.arrChunk = exports.toNumber = exports.formatNumberAsThousand = exports.percentToString = exports.getMRErrorStr = exports.parseCsv = exports.dateToString = exports.stringToDate = exports.getCreateScriptDeployment = exports.searchScriptById = exports.getScriptParams = exports.submitLogField = exports.trueOrFalse = exports.accDiv = exports.accMul = exports.Subtr = exports.accAdd = void 0;
    Papa = __importStar(Papa);
    //加法函数，用来得到精确的加法结果
    //说明：javascript的加法结果会有误差，在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
    //调用：accAdd(arg1,arg2)
    //返回值：arg1加上arg2的精确结果
    function accAdd(arg1, arg2) {
        if (!arg2) {
            arg2 = 0;
        }
        if (!arg1) {
            arg1 = 0;
        }
        arg1 = +arg1;
        arg2 = +arg2;
        var r1, r2, m, c;
        try {
            r1 = arg1.toString().split(".")[1].length;
        }
        catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        }
        catch (e) {
            r2 = 0;
        }
        c = Math.abs(r1 - r2);
        m = Math.pow(10, Math.max(r1, r2));
        if (c > 0) {
            var cm = Math.pow(10, c);
            if (r1 > r2) {
                arg1 = parseFloat(arg1.toString().replace(".", ""));
                arg2 = parseFloat(arg2.toString().replace(".", "")) * cm;
            }
            else {
                arg1 = parseFloat(arg1.toString().replace(".", "")) * cm;
                arg2 = parseFloat(arg2.toString().replace(".", ""));
            }
        }
        else {
            arg1 = parseFloat(arg1.toString().replace(".", ""));
            arg2 = parseFloat(arg2.toString().replace(".", ""));
        }
        return (arg1 + arg2) / m;
    }
    exports.accAdd = accAdd;
    //减法函数，用来得到精确的减法结果
    function Subtr(arg1, arg2) {
        if (!arg1) {
            arg1 = 0;
        }
        if (!arg2) {
            arg2 = 0;
        }
        var r1, r2, m, n;
        try {
            r1 = arg1.toString().split(".")[1].length;
        }
        catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        }
        catch (e) {
            r2 = 0;
        }
        m = Math.pow(10, Math.max(r1, r2));
        //last modify by deeka
        //动态控制精度长度
        n = (r1 >= r2) ? r1 : r2;
        return +((arg1 * m - arg2 * m) / m).toFixed(n);
    }
    exports.Subtr = Subtr;
    //乘法函数，用来得到精确的乘法结果
    //说明：javascript的乘法结果会有误差，在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
    //调用：accMul(arg1,arg2)
    //返回值：arg1乘以arg2的精确结果
    function accMul(arg1, arg2) {
        if (!arg1 || !arg2) {
            return 0;
        }
        arg1 = +arg1;
        arg2 = +arg2;
        var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
        try {
            m += s1.split(".")[1].length;
        }
        catch (e) {
        }
        try {
            m += s2.split(".")[1].length;
        }
        catch (e) {
        }
        return parseFloat(s1.replace(".", "")) * parseFloat(s2.replace(".", "")) / Math.pow(10, m);
    }
    exports.accMul = accMul;
    //除法函数，用来得到精确的除法结果
    //说明：javascript的除法结果会有误差，在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
    //调用：accDiv(arg1,arg2)
    //返回值：arg1除以arg2的精确结果
    function accDiv(arg1, arg2) {
        if (!arg1 || !arg2) {
            return 0;
        }
        var t1 = 0, t2 = 0, r1, r2;
        try {
            t1 = arg1.toString().split(".")[1].length;
        }
        catch (e) {
        }
        try {
            t2 = arg2.toString().split(".")[1].length;
        }
        catch (e) {
        }
        r1 = parseFloat(arg1.toString().replace(".", ""));
        r2 = parseFloat(arg2.toString().replace(".", ""));
        return (r1 / r2) * Math.pow(10, t2 - t1);
    }
    exports.accDiv = accDiv;
    //判断是真是假
    function trueOrFalse(val) {
        if (val) {
            if (val === 'T' || val === true) {
                return true;
            }
        }
        return false;
    }
    exports.trueOrFalse = trueOrFalse;
    function submitLogField(val) {
        //@ts-ignore
        record.submitFields(Object.assign({ type: (0, YLES_RELATED_RECORDTYPE_1.CustomRecordType)().DOSAGE_MRP_LOG }, val));
    }
    exports.submitLogField = submitLogField;
    //获取脚本传递的参数
    function getScriptParams(name) {
        return runtime.getCurrentScript().getParameter({ name: name });
    }
    exports.getScriptParams = getScriptParams;
    /**
     * 依据脚本英文ID，找到对应的脚本内部标识（数字ID）
     * @params id - 脚本英文ID全称
     * @return integer - 对应的脚本内部标识（数字ID）
     */
    function searchScriptById(id) {
        var script = '';
        if (id) {
            search.create({
                type: 'script', filters: [
                    ['scriptid', 'is', id]
                ]
            }).run().each(function (res) {
                script = res.id;
                return false;
            });
        }
        if (!script)
            throw 'there is no matched script by ' + id;
        log.debug('script', script);
        return script;
    }
    exports.searchScriptById = searchScriptById;
    //依据部署ID查找对应的脚本部署ID，若不存在则新建
    function getCreateScriptDeployment(obj) {
        const Search = search.create({
            type: 'scriptdeployment',
            filters: [['script.scriptid', 'is', obj.scriptId], 'and', ['scriptid', 'is', obj.depId]],
            columns: [{ name: 'internalid' }]
        });
        const data = Search.run().getRange({ start: 0, end: 1 });
        if (data.length === 0) {
            //若不存在此脚本部署，则新建
            const spId = searchScriptById(obj.scriptId);
            const rec = record.create({
                type: 'scriptdeployment',
                defaultValues: { 'script': spId }
            });
            rec.setValue('scriptid', obj.depId.replace('customdeploy', ''));
            rec.save();
        }
    }
    exports.getCreateScriptDeployment = getCreateScriptDeployment;
    //将str转为日期
    function stringToDate(str, type) {
        if (str) {
            if (type == 'YYYY/MM/DD' || type == 'MM/DD/YYYY') {
                return new Date(str);
            }
            else {
                if (typeof format.parse({ value: str, type: 'date' }) == 'object') {
                    return format.parse({ value: str, type: 'date' });
                }
            }
        }
        return '';
    }
    exports.stringToDate = stringToDate;
    //日期转为字符串
    function dateToString(date, type) {
        if (!date)
            return '';
        if (type == 'MM/DD/YYYY') {
            return addZero(date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear();
        }
        else if (type == 'YYYY/MM/DD') {
            return date.getFullYear() + '/' + addZero(date.getMonth() + 1) + '/' + date.getDate();
        }
        else {
            return format.format({ value: date, type: 'date' });
        }
    }
    exports.dateToString = dateToString;
    function addZero(n) {
        return n > 9 ? n : ('0' + n);
    }
    //将csv数据转为json
    function parseCsv(csvFile) {
        const ret = {};
        let index = 1;
        //循环CSV数组
        const iterator = csvFile.lines.iterator();
        //Skip the first line (CSV header)
        iterator.each(function () { return false; });
        iterator.each(function (line) {
            let errors = [];
            const lineValues = line.value.split(',');
            // log.debug('lineValues',lineValues);
            const item = (lineValues[0] || '').trim();
            const barcode = (lineValues[1] || '').trim();
            ret[item] = ret[item] || [];
            ret[item].push({
                barcode: barcode,
                line: index
            });
            index++;
            return true;
        });
        return ret;
    }
    exports.parseCsv = parseCsv;
    //获取MapReduce脚本的报错信息
    function getMRErrorStr(cxt) {
        let erStr = '';
        //INPUTDATA ERROR
        if (cxt.inputSummary.error) {
            erStr += cxt.inputSummary.error + ';\n';
        }
        //MAP ERROR
        cxt.mapSummary.errors.iterator().each(function (key, error, executionNo) {
            const mapEr = JSON.parse(error);
            erStr += mapEr.message + ';\n';
            return true;
        });
        //REDUCE ERROR
        cxt.reduceSummary.errors.iterator().each(function (key, error, executionNo) {
            const reduceEr = JSON.parse(error);
            erStr += reduceEr.message + ';\n';
            return true;
        });
        return erStr;
    }
    exports.getMRErrorStr = getMRErrorStr;
    //将百分比去除，返回数字
    function percentToString(percent) {
        if (percent)
            return String(percent).replace('%', '');
        return percent;
    }
    exports.percentToString = percentToString;
    /**
     * 将数字转为千分位显示
     * @param number            数值
     * @param decimals          保留小数位
     * @param decPoint         小数点符号
     * @param thousandsSep     千分位符号
     * @return {number}
     */
    function formatNumberAsThousand(number, decimals, decPoint, thousandsSep) {
        number = (number + '').replace(/[^0-9+-Ee.]/g, '');
        var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep, dec = (typeof decPoint === 'undefined') ? '.' : decPoint, s = '', toFixedFix = function (n, prec) {
            var k = Math.pow(10, prec);
            return '' + Math.floor(n * k) / k;
        };
        s = (prec ? toFixedFix(n, prec) : '' + Math.floor(n)).split('.');
        var re = /(-?\d+)(\d{3})/;
        while (re.test(s[0])) {
            s[0] = s[0].replace(re, "$1" + sep + "$2");
        }
        if ((s[1] || '').length < prec) {
            s[1] = s[1] || '';
            s[1] += new Array(prec - s[1].length + 1).join('0');
        }
        return s.join(dec);
    }
    exports.formatNumberAsThousand = formatNumberAsThousand;
    //千分位转化为数字
    function toNumber(str) {
        if (str) {
            str = String(str).replace(/,/g, '');
            return parseFloat(str);
        }
        return 0;
    }
    exports.toNumber = toNumber;
    //数组切片
    function arrChunk(arr, size) {
        if (arr.length === 0) {
            return [];
        }
        const tempArr = [];
        const len = Math.ceil(arr.length / size);
        let last = 0;
        for (let i = 0; i < len; i++) {
            if (size * i >= arr.length) {
                last = arr.length;
            }
            else {
                last = size * i + size;
            }
            tempArr.push(arr.slice(size * i, last));
        }
        return tempArr;
    }
    exports.arrChunk = arrChunk;
    //校验导入的CSV数据
    function validateData(csvFile, rid) {
        //获取所有的Item信息
        const itemInfo = (0, YLES_SEARCH_TOOL_1.getAllItem)();
        const csvBarcode = [];
        const folderId = (0, YLES_SEARCH_TOOL_1.getCsvFolder)();
        //创建校验成功的CSV数据文件
        const ckSuccessCsv = file.create({
            fileType: file.Type.CSV,
            name: 'checkSuccessCsv_' + new Date().getTime(),
            folder: folderId
        });
        ckSuccessCsv.encoding = 'GB18030'; //file.Encoding.GB18030;//UTF_8
        ckSuccessCsv.appendLine({
            value: 'itemId,barcode'
        });
        //创建校验错误的CSV文件
        const ckErrorCsv = file.create({
            fileType: file.Type.CSV,
            name: 'checkErrorCsv_' + new Date().getTime(),
            folder: folderId
        });
        ckErrorCsv.encoding = 'GB18030'; //file.Encoding.GB18030;//UTF_8
        ckErrorCsv.appendLine({
            value: 'itemId,barcode,原行号,错误提示'
        });
        const sd = (new Date).getTime();
        //是否全部通过校验
        let validatePass = true;
        //是否存在正确的明细行
        let hasSuccessLine = 0;
        //循环CSV数组
        const iterator = csvFile.lines.iterator();
        //Skip the first line (CSV header)
        iterator.each(function () { return false; });
        iterator.each(function (line) {
            let errors = [];
            const lineValues = line.value.split(',');
            // log.debug('lineValues',lineValues);
            const item = (lineValues[0] || '').trim();
            const barcode = (lineValues[1] || '').trim();
            const bcAr = barcode.replace(item, '').split('-');
            /**
             * ①：校验item
             * 字段的值为货品的itemid字段值，需要校验货品ID在系统内是否存在
             */
            if (!item || !itemInfo.includes(item)) {
                errors.push(`货品ID不存在;`);
                validatePass = false;
            }
            /**
             * ②：校验barcode
             * 【条码】的格式校验：【条码】组成规则为 货品ID-YYYYMMDD-99999999。需要校验CSV内提供的条码是否符合组成规则。具体说明如下：
             * 【货品ID】部分需要与CSV文件当前行的第一个字段的值保持一致，【YYYYMMDD】部分为8位年月日，【99999999】部分为8位随机数字
             */
            if (barcode.indexOf(item) != 0) {
                //是否以itemid开头
                errors.push(`条码不符合规则;`);
                validatePass = false;
            }
            else if (!/^(\d{8})$/.test(bcAr[2])) {
                //结束是否是8位流水号
                errors.push(`条码不符合规则;`);
                validatePass = false;
            }
            else {
                if (!/^(\d{4})(\d{2})(\d{2})$/.test(bcAr[1])) {
                    //中间是否是 YYYYMMDD
                    errors.push(`条码不符合规则;`);
                    validatePass = false;
                }
                else {
                    //中间是否是有效日期
                    // @ts-ignore
                    if (new Date(bcAr[1].substr(0, 4) + '/' + bcAr[1].substr(4, 2) + '/' + bcAr[1].substr(6, 2)) == 'Invalid Date') {
                        errors.push(`条码不符合规则;`);
                        validatePass = false;
                    }
                }
            }
            /**
             * ③： 校验重复
             * CSV文件内，货品ID+条码维度，是否有重复
             */
            if (csvBarcode.includes(barcode)) {
                errors.push(`本条数据与原文件内第${csvBarcode.indexOf(barcode) + 1}行重复;`);
                validatePass = false;
            }
            csvBarcode.push(barcode);
            //将校验失败的数据存储在错误文件中
            if (errors.length > 0) {
                ckErrorCsv.appendLine({
                    value: `${item},${barcode},${csvBarcode.length},${errors.toString().replace(/,/g, '').replace(/;$/, "")}`
                });
            }
            else {
                ckSuccessCsv.appendLine({
                    value: `${item},${barcode}`
                });
                hasSuccessLine++;
            }
            //若传入日志记录，则输出session
            if (rid) {
                if (csvBarcode.length % 10000 == 0) {
                    setImpLogCheckedLine(rid, csvBarcode.length);
                    log.debug({ title: '已校验', details: csvBarcode.length + '条数据' });
                }
            }
            return true;
        });
        if (rid)
            setImpLogCheckedLine(rid, csvBarcode.length);
        const ed1 = (new Date).getTime();
        log.debug({ title: '处理数据耗费的时间', details: ed1 - sd });
        let ckErrorId = '';
        let ckSuccessCsvId = '';
        if (!validatePass) {
            ckErrorId = ckErrorCsv.save();
            log.debug({ title: '成功创建校验失败CSV文件ID:', details: ckErrorId });
        }
        const ed2 = (new Date).getTime();
        log.debug({ title: '保存ckErrorCsv的时间', details: ed2 - ed1 });
        if (hasSuccessLine > 0) {
            ckSuccessCsvId = ckSuccessCsv.save();
            log.debug({ title: '成功创建校验成功CSV文件ID', details: ckSuccessCsvId });
        }
        const ed3 = (new Date).getTime();
        log.debug({ title: '保存ckSuccessCsv的时间', details: ed3 - ed2 });
        return { pass: validatePass, status: '', ckErrorId, ckSuccessCsvId, successLine: hasSuccessLine };
    }
    exports.validateData = validateData;
    //使用papaparse校验数据
    function PapaValidateData(csvFile, rid) {
        const paData = Papa.parse(csvFile.url, { header: true, skipEmptyLines: 'greedy', fastMode: true });
        log.debug({ title: 'paData', details: paData });
        const data = paData.data;
        log.debug({ title: 'data', details: data });
        data.map(function (d, index) {
            log.debug({ title: 'data detail', details: d });
        });
        const rt = {};
        return rt;
    }
    exports.PapaValidateData = PapaValidateData;
    //设置已校验的行数
    function setImpLogCheckedLine(rid, num) {
        record.submitFields({
            type: (0, YLES_RELATED_RECORDTYPE_1.CustomRecordType)().IMPORT_ITEM_BARCODE_LOG,
            id: rid,
            values: {
                custrecord_yles_ckd_line_no: num.toString()
            }
        });
    }
    //更新导入日志
    function changeImportLog(validateRes, importLog) {
        let values = {};
        if (validateRes.pass == false) {
            values.custrecord_yles_status = '4'; //校验出错
            values.custrecord_yles_ck_error_csv = validateRes.ckErrorId;
            values.custrecord_yles_imp_success_csv = validateRes.ckSuccessCsvId;
            values.custrecord_yles_imp_csv_line_no = validateRes.successLine;
            values.custrecord_yles_end_time = new Date();
        }
        else {
            values.custrecord_yles_status = '7'; //校验成功
            values.custrecord_yles_ck_error_csv = '';
            values.custrecord_yles_imp_success_csv = validateRes.ckSuccessCsvId;
            values.custrecord_yles_imp_csv_line_no = validateRes.successLine;
        }
        record.submitFields({ type: (0, YLES_RELATED_RECORDTYPE_1.CustomRecordType)().IMPORT_ITEM_BARCODE_LOG, id: importLog, values: values });
    }
    exports.changeImportLog = changeImportLog;
});
